home *** CD-ROM | disk | FTP | other *** search
- ///--------------------------------------------------------------------------------------
- // Scrolling Demo.c
- //
- // By Vern Jensen. Created in August of 1995
- ///--------------------------------------------------------------------------------------
-
-
- #include <SWFPSReport.h>
- #include <SWIncludes.h>
- #include <SWGameUtils.h>
-
- #include "SWApplication.h"
- #include "Scrolling Demo.h"
-
-
- #define kFullScreenWindow false // Try me full screen!
- #define kWorldRectInset 0 // Make the SpriteWorld smaller?
- #define kInterlacedMode true // Turns Interlaced mode on/off
- #define kSyncToVBL false // Sync SpriteWorld to VBL?
- #define kMaxFPS 30 // Set to 0 for unrestricted speed
-
-
- #define kSpriteMoveDelta 20 // Try 5, 10, 20, or 40
- #define kDiamondSpace 8 // How far apart the diamonds are spaced
- // (try 1!)
-
- #define kSpriteMoveDistance 80 // How far the sprite can move from
- // the center of the screen, in pixels.
- // Try making this value higher!
-
- // Number of ticks to wait before changing tile image; 0 = change every frame
- #define kDiamondFrameRate 8 // How often diamond tiles change frames
- #define kWallFrameRate 120 // How often wall changes frames
-
- #define kBWPictResIDOffset 100
- #define kTileWidth 40
- #define kTileHeight 40
- #define kTileMapRows 100
- #define kTileMapCols 150
-
- #define kStartRow 5 // Starting position of sprite
- #define kStartCol 5 // in tile col and row
-
-
- #define kLeftArrowKey 0x7B
- #define kRightArrowKey 0x7C
- #define kDownArrowKey 0x7D
- #define kUpArrowKey 0x7E
-
- #define kLeftKeyPad 0x56
- #define kRightKeyPad 0x58
- #define kDownKeyPad 0x54
- #define kUpKeyPad 0x5B
-
- #define kEscKey 0x35
-
-
- #define kNoKey 0
- #define kLeftKey 1
- #define kUpKey 2
- #define kRightKey 3
- #define kDownKey 4
-
-
- enum tileIDs
- {
- kWallTile,
- kLastWallTile,
- kGrassTile,
- kBlackTile,
- kDiamondTile,
- kDiamondTile2,
- kLastDiamondTile,
-
- kTunnelTile1,
- kTunnelTile2,
- kTunnelTile3,
- kTunnelTile4,
- kTunnelTile5,
- kTunnelTile6,
- kWireTile1,
- kWireTile2,
-
- kMaxNumTiles
- };
-
-
-
- /***********/
- /* Globals */
- /***********/
-
- SpriteWorldPtr gSpriteWorldP;
- TileMapPtr gTileMap;
- SpritePtr gSimpleSpriteP;
- WindowPtr gWindowP;
- Rect gScreenMidRect;
-
- short gKeys[4]; // Stores keys in order that they were pressed
- short gNumKeys = 0; // Number of keys in gKeys array
-
-
-
-
- ///--------------------------------------------------------------------------------------
- // Main
- ///--------------------------------------------------------------------------------------
-
- void main( void )
- {
- Initialize(kNumberOfMoreMastersCalls);
-
- if (SWHasSystem7())
- {
- AllowKeyUpEvents(); // Part of SWGameUtils.c
- SetCursor(*GetCursor(watchCursor));
-
- CreateSpriteWorld();
- CreateSprites();
-
- SetCursor(&qd.arrow);
- HideCursor();
-
- SetUpAnimation();
- RunAnimation();
- ShutDown();
-
- RestoreEventMask(); // Call this after AllowKeyUpEvents
- }
- else
- {
- CantRunOnThisMachine();
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // CreateSpriteWorld
- ///--------------------------------------------------------------------------------------
-
-
- void CreateSpriteWorld( void )
- {
- Rect offscreenRect, worldRect, windRect;
- RgnHandle mBarUpdateRgn;
- OSErr err;
- short row, col;
- short resIDOffset;
-
- gWindowP = GetNewCWindow(kWindowResID, NULL, (WindowPtr)-1L);
-
- if (gWindowP != NULL)
- {
- if (kFullScreenWindow == true)
- {
- SizeWindow(gWindowP, qd.screenBits.bounds.right,
- qd.screenBits.bounds.bottom, false);
- MoveWindow(gWindowP, 0, 0, false);
- }
- else
- {
- // Center window in screen
- windRect = gWindowP->portRect;
- CenterRect(&windRect, &qd.screenBits.bounds);
- MoveWindow(gWindowP, windRect.left, windRect.top, false);
- }
-
- ShowWindow(gWindowP);
- SetPort(gWindowP);
- mBarUpdateRgn = HideMenuBar(gWindowP); // Must be done *after* showing window!
- EraseRgn(mBarUpdateRgn);
-
- if (kInterlacedMode)
- PaintRect(&gWindowP->portRect); // Blacken window for Interlaced mode
- }
- else
- CantFindResource();
-
-
- err = SWEnterSpriteWorld();
- FatalError(err);
-
-
- worldRect = gWindowP->portRect;
- InsetRect(&worldRect, kWorldRectInset, kWorldRectInset);
-
-
- // Set size of offscreen area
- offscreenRect = worldRect;
- OffsetRect(&offscreenRect, -offscreenRect.left, -offscreenRect.top);
-
-
- // Make offscreen area evenly divisible by tile width & height
- if ( (offscreenRect.right/kTileWidth)*kTileWidth != offscreenRect.right)
- offscreenRect.right = (offscreenRect.right/kTileWidth)*kTileWidth + kTileWidth;
-
- if ( (offscreenRect.bottom/kTileHeight)*kTileHeight != offscreenRect.bottom)
- offscreenRect.bottom = (offscreenRect.bottom/kTileHeight)*kTileHeight + kTileHeight;
-
-
- // Create the scrolling sprite world
- err = SWCreateSpriteWorldFromWindow(&gSpriteWorldP, (CWindowPtr)gWindowP,
- &worldRect, &offscreenRect);
- FatalError(err);
-
-
-
- err = SWInitTiling(gSpriteWorldP, kTileHeight, kTileWidth, kMaxNumTiles);
- FatalError(err);
-
- err = SWCreateTileMap(gSpriteWorldP, &gTileMap, kTileMapRows, kTileMapCols);
- FatalError(err);
-
-
- // Determine whether to load B&W or color graphics
- if (gSpriteWorldP->pixelDepth == 1)
- resIDOffset = kBWPictResIDOffset;
- else
- resIDOffset = 0;
-
- // Load first set of tiles
- err = SWLoadTilesFromPictResource(
- gSpriteWorldP,
- kWallTile, // startTileID
- kLastDiamondTile, // endTileID
- 200 + resIDOffset, // pictResID
- 0, // maskResID
- kNoMask, // maskType
- 1, // horizBorderWidth
- 1); // vertBorderHeight
- FatalError(err);
-
- // Load masked set of tiles
- err = SWLoadTilesFromPictResource(
- gSpriteWorldP,
- kTunnelTile1, // startTileID
- kWireTile2, // endTileID
- 201 + resIDOffset, // pictResID
- 401, // maskResID
- kFatMask, // maskType
- 1, // horizBorderWidth
- 1); // vertBorderHeight
- FatalError(err);
-
-
- // Set up tileMap
- for (row = 0; row < kTileMapRows; row++)
- {
- for (col = 0; col < kTileMapCols; col++)
- {
- if (row == 0 || col == 0 || row == kTileMapRows-1 || col == kTileMapCols-1)
- gTileMap[row][col] = kWallTile;
- else if (row > kTileMapRows / 2)
- gTileMap[row][col] = kWireTile1;
- else if ((row/kDiamondSpace)*kDiamondSpace == row &&
- (col/kDiamondSpace)*kDiamondSpace == col)
- gTileMap[row][col] = kDiamondTile;
- else
- gTileMap[row][col] = kGrassTile;
- }
- }
-
-
- // Add tunnel to tileMap
- row = kTileMapRows / 2;
-
- for (col = 1; col < kTileMapCols-1; col += 2)
- {
- gTileMap[row][col] = kTunnelTile1;
- gTileMap[row][col+1] = kTunnelTile2;
- gTileMap[row+1][col] = kTunnelTile4;
- gTileMap[row+1][col+1] = kTunnelTile5;
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // CreateSprites
- ///--------------------------------------------------------------------------------------
-
- void CreateSprites( void )
- {
- SpriteLayerPtr spriteLayerP;
- OSErr err;
-
-
- // Create the sprite layer
- err = SWCreateSpriteLayer(&spriteLayerP);
- FatalError(err);
-
- // Create the main sprite
- err = SWCreateSpriteFromCicnResource(gSpriteWorldP, &gSimpleSpriteP, NULL,
- 128, 1, kFatMask);
- FatalError(err);
-
-
- // Set up the sprite
- SWSetSpriteUnderTiles(gSimpleSpriteP, true);
- SWSetSpriteMoveProc(gSimpleSpriteP, KeySpriteMoveProc);
- SWSetSpriteLocation(gSimpleSpriteP, kStartCol * kTileWidth, kStartRow * kTileHeight);
- SWSetSpriteMoveDelta(gSimpleSpriteP, 0, 0);
-
- // Set the sprite's drawProc
- if (gSpriteWorldP->pixelDepth == 8) // If in 256 colors
- {
- if (kInterlacedMode)
- SWSetSpriteDrawProc(gSimpleSpriteP, BP8BitInterlacedMaskDrawProc);
- else
- SWSetSpriteDrawProc(gSimpleSpriteP, BlitPixie8BitMaskDrawProc);
- }
- else // Not 256 colors
- {
- #if !SW_PPC // No BlitPixieAllBit in PPC compiles
- // Use interlaced drawProcs unless in B&W, where interlacing is ugly
- if (kInterlacedMode && gSpriteWorldP->pixelDepth != 1)
- SWSetSpriteDrawProc(gSimpleSpriteP, BPAllBitInterlacedMaskDrawProc);
- else
- SWSetSpriteDrawProc(gSimpleSpriteP, BlitPixieAllBitMaskDrawProc);
- #endif
- }
-
- SWAddSprite(spriteLayerP, gSimpleSpriteP);
- SWAddSpriteLayer(gSpriteWorldP, spriteLayerP);
-
- SWLockSpriteWorld(gSpriteWorldP);
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SetUpAnimation
- ///--------------------------------------------------------------------------------------
-
- void SetUpAnimation( void )
- {
- Rect moveBoundsRect;
-
- // Set up data used by the SmoothScrollingWorldMoveProc
- gScreenMidRect = gSimpleSpriteP->curFrameP->frameRect;
- CenterRect( &gScreenMidRect, &gSpriteWorldP->backRect );
-
- SWSetSpriteWorldMaxFPS(gSpriteWorldP, kMaxFPS);
- SWSyncSpriteWorldToVBL(gSpriteWorldP, kSyncToVBL);
-
- // movement boundary = size of tileMap
- SetRect(&moveBoundsRect, 0,0, kTileMapCols * kTileWidth, kTileMapRows * kTileHeight);
-
- SWSetScrollingWorldMoveBounds(gSpriteWorldP, &moveBoundsRect);
- SWSetScrollingWorldMoveProc(gSpriteWorldP, SmoothScrollingWorldMoveProc, gSimpleSpriteP);
-
- SWSetTileChangeProc(gSpriteWorldP, TileChangeProc);
-
- // Move visScrollRect to starting sprite position
- SWMoveVisScrollRect(gSpriteWorldP,
- gSpriteWorldP->followSpriteP->destFrameRect.left - gSpriteWorldP->backRect.right/2,
- gSpriteWorldP->followSpriteP->destFrameRect.top - gSpriteWorldP->backRect.bottom/2);
-
-
- if (gSpriteWorldP->pixelDepth == 8) // If in 256 colors
- {
- if (kInterlacedMode)
- {
- SWSetSpriteWorldScreenDrawProc(gSpriteWorldP, BP8BitInterlacedRectDrawProc);
- SWSetSpriteWorldOffscreenDrawProc(gSpriteWorldP, BP8BitInterlacedRectDrawProc);
- SWSetTileMaskDrawProc(gSpriteWorldP, BP8BitInterlacedPartialMaskDrawProc);
- }
- else
- {
- SWSetSpriteWorldOffscreenDrawProc(gSpriteWorldP, BlitPixie8BitRectDrawProc);
- SWSetSpriteWorldScreenDrawProc(gSpriteWorldP, BlitPixie8BitRectDrawProc);
- SWSetTileMaskDrawProc(gSpriteWorldP, BlitPixie8BitPartialMaskDrawProc);
- }
- }
- else // Not 256 colors
- {
- #if !SW_PPC // No BlitPixieAllBit in PPC compiles
- if (kInterlacedMode && gSpriteWorldP->pixelDepth != 1)
- {
- // Use interlaced drawProcs unless in B&W, where interlacing is ugly
- SWSetSpriteWorldScreenDrawProc(gSpriteWorldP, BPAllBitInterlacedRectDrawProc);
- SWSetSpriteWorldOffscreenDrawProc(gSpriteWorldP, BPAllBitInterlacedRectDrawProc);
- SWSetTileMaskDrawProc(gSpriteWorldP, BPAllBitInterlacedPartialMaskDrawProc);
- }
- else
- {
- SWSetSpriteWorldOffscreenDrawProc(gSpriteWorldP, BlitPixieAllBitRectDrawProc);
- SWSetSpriteWorldScreenDrawProc(gSpriteWorldP, BlitPixieAllBitRectDrawProc);
- SWSetTileMaskDrawProc(gSpriteWorldP, BlitPixieAllBitPartialMaskDrawProc);
- }
- #endif
- }
-
-
- ForeColor(blackColor);
- BackColor(whiteColor);
-
- SWDrawTilesInBackground(gSpriteWorldP);
- SWUpdateScrollingSpriteWorld(gSpriteWorldP, true);
- }
-
-
- ///--------------------------------------------------------------------------------------
- // RunAnimation
- ///--------------------------------------------------------------------------------------
-
-
- void RunAnimation( void )
- {
- unsigned long frames;
-
- frames = 0;
- StartTimer();
-
-
- while (!Button())
- {
- SWProcessScrollingSpriteWorld(gSpriteWorldP);
- SWAnimateScrollingSpriteWorld(gSpriteWorldP);
-
- if (gSpriteWorldP->frameHasOccured)
- frames++;
- }
-
-
- ShowMenuBar(gWindowP);
- ShowResults(frames);
- }
-
-
- ///--------------------------------------------------------------------------------------
- // ShutDown (clean up and dispose of the SpriteWorld)
- ///--------------------------------------------------------------------------------------
-
-
- void ShutDown( void )
- {
- SWDisposeSpriteWorld(gSpriteWorldP);
- SWExitSpriteWorld();
-
- FlushEvents(everyEvent, 0);
- ShowCursor();
- }
-
-
- ///--------------------------------------------------------------------------------------
- // TileChangeProc
- ///--------------------------------------------------------------------------------------
-
-
- void TileChangeProc(
- SpriteWorldPtr spriteWorldP)
- {
- short curImage;
- static short wallDelay = 0, diamondDelay = 0;
- static short oldTicks = 0;
- short ticksPassed, ticks;
-
- // Initialize oldTicks the first time this function is called
- if (oldTicks == 0)
- oldTicks = TickCount();
-
- ticks = TickCount();
- ticksPassed = ticks - oldTicks; // Number of ticks passed since last call
- oldTicks = ticks;
-
- // kWallTile
- wallDelay += ticksPassed;
- if (wallDelay >= kWallFrameRate)
- {
- curImage = spriteWorldP->curTileImage[kWallTile];
- if (curImage < kLastWallTile)
- curImage++;
- else
- curImage = kWallTile;
-
- SWChangeTileImage(spriteWorldP, kWallTile, curImage);
- wallDelay = 0;
- }
-
-
- // kDiamondTile
- diamondDelay += ticksPassed;
- if (diamondDelay >= kDiamondFrameRate)
- {
- curImage = spriteWorldP->curTileImage[kDiamondTile];
- if (curImage < kLastDiamondTile)
- curImage++;
- else
- curImage = kDiamondTile;
-
- SWChangeTileImage(spriteWorldP, kDiamondTile, curImage);
- diamondDelay = 0;
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // KeySpriteMoveProc
- ///--------------------------------------------------------------------------------------
-
-
- void KeySpriteMoveProc(SpritePtr srcSpriteP)
- {
- short row, col;
- short rowDelta, colDelta;
- short tile;
-
- UpdateKeys(); // Put the latest key values in the keys structure
-
-
- row = srcSpriteP->destFrameRect.top / kTileHeight;
- col = srcSpriteP->destFrameRect.left / kTileWidth;
-
- if (row * kTileHeight == srcSpriteP->destFrameRect.top &&
- col * kTileWidth == srcSpriteP->destFrameRect.left)
- {
- tile = gTileMap[row][col];
-
- // Leave black trail behind sprite
- if (tile == kGrassTile || tile == kDiamondTile)
- SWDrawTile(gSpriteWorldP, row, col, kBlackTile);
- else if (tile == kTunnelTile2 || tile == kTunnelTile5 || tile == kWireTile1)
- SWDrawTile(gSpriteWorldP, row, col, tile+1);
-
-
- rowDelta = 0;
- colDelta = 0;
-
- if (gKeys[0] == kLeftKey)
- colDelta = -1;
- else if (gKeys[0] == kRightKey)
- colDelta = 1;
- else if (gKeys[0] == kUpKey)
- rowDelta = -1;
- else if (gKeys[0] == kDownKey)
- rowDelta = 1;
-
-
-
- tile = gTileMap[row + rowDelta][col + colDelta];
-
- if (tile != kWallTile && tile != kTunnelTile1 && tile != kTunnelTile4)
- {
- srcSpriteP->vertMoveDelta = rowDelta * kSpriteMoveDelta;
- srcSpriteP->horizMoveDelta = colDelta * kSpriteMoveDelta;
- }
- else
- {
- srcSpriteP->vertMoveDelta = 0;
- srcSpriteP->horizMoveDelta = 0;
- }
- }
-
- SWOffsetSprite(srcSpriteP, srcSpriteP->horizMoveDelta, srcSpriteP->vertMoveDelta);
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SmoothScrollingWorldMoveProc - our scrolling WorldMoveProc
- ///--------------------------------------------------------------------------------------
-
-
- void SmoothScrollingWorldMoveProc(
- SpriteWorldPtr spriteWorldP,
- SpritePtr followSpriteP)
- {
- short screenMidRectTop, screenMidRectLeft;
-
- screenMidRectTop = gScreenMidRect.top + spriteWorldP->visScrollRect.top;
- screenMidRectLeft = gScreenMidRect.left + spriteWorldP->visScrollRect.left;
-
-
- spriteWorldP->horizScrollDelta = (kSpriteMoveDelta *
- (followSpriteP->destFrameRect.left - screenMidRectLeft) ) / kSpriteMoveDistance;
-
- spriteWorldP->vertScrollDelta = (kSpriteMoveDelta *
- (followSpriteP->destFrameRect.top - screenMidRectTop) ) / kSpriteMoveDistance;
-
- if (kInterlacedMode)
- spriteWorldP->vertScrollDelta = spriteWorldP->vertScrollDelta>>1<<1;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // UpdateKeys (Put the latest key values in the keys structure)
- ///--------------------------------------------------------------------------------------
-
-
- void UpdateKeys( void )
- {
- EventRecord event;
- short theKey, newKey, n;
-
-
- while ( GetOSEvent( (keyUpMask | keyDownMask), &event ) )
- {
- theKey = (event.message & keyCodeMask) >> 8;
-
- switch (theKey)
- {
- case kLeftArrowKey:
- case kLeftKeyPad:
- newKey = kLeftKey;
- break;
- case kRightArrowKey:
- case kRightKeyPad:
- newKey = kRightKey;
- break;
- case kDownArrowKey:
- case kDownKeyPad:
- newKey = kDownKey;
- break;
- case kUpArrowKey:
- case kUpKeyPad:
- newKey = kUpKey;
- break;
- default:
- newKey = kNoKey;
- }
-
- if (newKey)
- {
- if (event.what == keyDown)
- {
- // Store keys in order pressed
- for (n = gNumKeys; n > 0; n--)
- gKeys[n] = gKeys[n-1];
- gKeys[0] = newKey;
- gNumKeys++;
- }
- else if (event.what == keyUp)
- {
- // Remove key from list
- gNumKeys--;
- for (n = 0; gKeys[n] != newKey; n++);
- while (n < gNumKeys)
- {
- gKeys[n] = gKeys[n+1];
- n++;
- }
-
- gKeys[gNumKeys] = 0;
- }
- }
- }
- }
-